use actix_web::{error, post, web, App, HttpResponse, HttpServer, Responder, Result};
use serde::Deserialize;

#[derive(Deserialize)]
struct Info {
    username: String,
}

/// 将请求体反序列化为Info,限制请求体大小为4kb
/// ```
/// POST / HTTP/1.1
/// Host: localhost:8080
/// Content-Type: application/json
/// Content-Length: 42
///
/// {
///     "age":19,
///     "username":"御坂美琴"
/// }
/// ```
async fn index(info: web::Json<Info>) -> impl Responder {
    format!("Welcome {}!", info.username)
}

/// 使用 serde 提取表单数据 仅当内容类型为 x-www-form-urlencoded
/// 并且请求的内容可以反序列化为“FormData”结构时才会调用此处理程序
/// ```
/// POST /form HTTP/1.1
/// Host: localhost:8080
/// Content-Type: application/x-www-form-urlencoded
/// Content-Length: 45
///
/// username=%E7%99%BD%E4%BA%95%E9%BB%91%E5%AD%90
/// ```
#[post("/form")]
async fn index_01(form: web::Form<Info>) -> Result<String> {
    Ok(format!("Welcome {}!", form.username))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        let json_config = web::JsonConfig::default()
            .limit(4096)
            .error_handler(|err, _req| {
                error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into()
            });

        App::new().service(
            web::resource("/")
                .app_data(json_config)
                .route(web::post().to(index)),
        )
            .service(index_01)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
